home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / cram_v21.zip / CRAM.C next >
C/C++ Source or Header  |  1990-12-31  |  15KB  |  440 lines

  1. /*
  2.  *   ------------------------------------
  3.  *   C R A M   -   the ASCII file reducer
  4.  *   ------------------------------------
  5.  *
  6.  *   CRAM  -  ASCII File Reducer  - V2.1
  7.  *   Copyright (c) 1988-90  -  Dean Tutterow  -  All Rights Reserved
  8.  *   
  9.  *   What  does  it do?   It crams as  much text  as possible onto a page
  10.  *   in  reduced format.   Using  subscript characters as  the font on an
  11.  *   Epson printer,  you  can print up to 79 characters wide and 154 rows
  12.  *   long in 2 columns.   That  works  out to  5-6 pages of  text on each
  13.  *   printed  page.   In  normal use  with  files with embedded formfeeds
  14.  *   respected, you get 4 pages of text on each printed page.
  15.  *
  16.  *   CRAM  was  written  after  I  had  printed  another  of  those  LONG
  17.  *   documentation files.  I was tired of those STACKS of listings, etc.,
  18.  *   that  gathered  dust  simply  because they  were too much trouble to
  19.  *   handle  once I printed  them.   Now  the  printed listings are small
  20.  *   enough to keep in notebooks.   As a bonus, CRAM is especially useful
  21.  *   for printing program listings.  The reduced format is just the thing
  22.  *   to show program structure and the BIG picture!
  23.  *
  24.  *   While not limited to Epson printers,  it is hardcoded for my FX-86e.
  25.  *   Of course you can provide your own setup and un-setup codes for your
  26.  *   printer, and include them in a printer setup file for CRAM to use.
  27.  *
  28.  *   USAGE:
  29.  *   
  30.  *   CRAM srcfile crammedfile [/options]
  31.  *
  32.  *   where [/options] are:
  33.  *          /COLUMN=n       with 1 ≤ n ≥ 10
  34.  *          /FF             if <FF> encountered, align to next logical page
  35.  *          /LARGE          use PICA format to get 137 characters/line
  36.  *          /PAGELENGTH=n   may vary printed page length from 1-154 lines
  37.  *          /SKIP=n         number of columns to ignore in srcfile
  38.  *          /WHITE=n        number of characters of whitespace on left of page
  39.  *   
  40.  *   The  srcfile  should  be  a  valid DOS filename;  wildcards  are not
  41.  *   accepted.   You  need  only  supply  enough  to the  option  name to
  42.  *   distinguish it from the other options, for example /C=1 and /R.
  43.  *   
  44.  *   As a daily VAX user,  I  have tried to implement the straightforward
  45.  *   command-line interface that VMS affords the user.  While the srcfile
  46.  *   and crammedfile must be in that order,  the options may be spread at
  47.  *   will along the command line.
  48.  *
  49.  *   The options are much easier understood after a few practice sessions.
  50.  *   '/COLUMN=n' is  used whenever you want more or less than the standard
  51.  *   two columns on each page.   While  normally  defaulted  to two-column
  52.  *   operation, only the first 79 characters on each line (unless some are
  53.  *   /SKIP-ped) are  visible.   '/FF' respects  embedded  formfeeds in the
  54.  *   text.   Normally off, this option moves to the next logical page when
  55.  *   encountered.   The pagelength is adjustable  through  '/PAGELENGTH=n'
  56.  *   The default is 132 rows,  which allows two pages in each column since
  57.  *   most formatters place 66 lines per page.  If you want your one-column
  58.  *   printing shifted right on the page so that you have whitespace on the
  59.  *   left  side of the page,  then '/WHITE' is just the ticket.   Finally,
  60.  *   '/SKIP=n' ignores the first 'n' characters on each line.  This allows
  61.  *   you  to  print  79  useful  characters  in each  column when printing
  62.  *   formatted files with spaces or tabs in the first 'n' columns.
  63.  */
  64.  
  65. #include <stdio.h>
  66. #include <string.h>
  67.  
  68. /*  G L O B A L   D E F I N E S  */
  69. #define byte         unsigned char
  70. #define MAX_CHAR     161
  71. #define MAX_ROWS     154
  72. #define MAX_ELEMENTS 8
  73. #define PICA         137
  74. #define ELITE        160
  75.  
  76.  
  77. /*  E R R O R   C O D E S  */
  78. #define FILENAME_TROUBLE    0x101
  79. #define INVALID_OPTION      0x102
  80. #define MISSING_FILE        0x103
  81. #define INVLD_NUM_COLUMNS   0x104
  82.  
  83. /*  S E V E R I T Y   C O D E S  */
  84. #define FATAL         "F"
  85. #define SEVERE        "S"
  86. #define WARNING       "W"
  87. #define INFORMATIONAL "I"
  88.  
  89. /*  G L O B A L   D A T A  */ 
  90. char    BUFFER[MAX_ROWS][MAX_CHAR];
  91. char    PRINTER_INIT[200];
  92. char    PRINTER_TERM[200];
  93. int     SKIP_PT   = 0;
  94. int     NUM_COLS  = 2;
  95. int     NUM_CHAR  = MAX_CHAR - 1;
  96. int     NUM_ROWS  = MAX_ROWS;
  97. byte    NUM_FILES = 0;
  98. byte    WHITE     = 0;
  99. byte    FF        = 0;
  100. byte    DISPLAYABLE;
  101. byte    LEFT_EDGE;
  102. char    *INFILE, *OUTFILE;
  103. FILE    *INPUT,  *OUTPUT;
  104.  
  105.  
  106. main (argc,argv)
  107.  
  108. int    argc;
  109. char    *argv[];
  110. {
  111.         int     i, j, carryover, value, lr, lc, current_col;
  112.         char    equivalence[100], parsed[120], *elements[MAX_ELEMENTS];
  113.         char    *option, *parse_option(), *status, *file_status, line[161];
  114.  
  115.         /* Tell them who I am. */
  116.         print_copyright ();
  117.  
  118.         /* Parse the command line for files and switches. */
  119.         memset (equivalence, '\0', sizeof (equivalence));
  120.     memset (parsed, '\0', sizeof (parsed));
  121.     for (i = 0; i < argc; i++) { 
  122.             strcat (equivalence, argv[i]);
  123.             strcat (equivalence, " ");
  124.         };
  125.         value = MAX_ELEMENTS;
  126.     parse_command_line (equivalence, parsed, elements, &value);
  127.     get_filenames_and_options (elements, &value, &INFILE, &OUTFILE);
  128.         get_printer_defaults ();
  129.     if (NUM_FILES != 2) err_exit (MISSING_FILE, FATAL);
  130.     if (NUM_ROWS > MAX_ROWS) NUM_ROWS = MAX_ROWS;
  131.     
  132.         /* Open the proper files for reading/writing. */
  133.         INPUT  = fopen (INFILE,  "rt");
  134.     OUTPUT = fopen (OUTFILE, "wt");
  135.         if (!INPUT || !OUTPUT) err_exit (FILENAME_TROUBLE, FATAL);
  136.     
  137.         /* Send the printer setup string. */
  138.         fputs (PRINTER_INIT, OUTPUT);
  139.  
  140.         /* Compute the maximum displayable portion of the input line. */
  141.         DISPLAYABLE = ( NUM_CHAR - NUM_COLS + 1 - WHITE ) / NUM_COLS;
  142.  
  143.         /* Read from the input file and build the output file in memory. */
  144.         carryover = 0;
  145.         do {
  146.             LEFT_EDGE = WHITE;
  147.             memset (BUFFER, ' ', NUM_ROWS * MAX_CHAR);
  148.             for ( i=0; i < NUM_ROWS; i++ ) BUFFER[i][NUM_CHAR] = 0;
  149.             for ( current_col=1,lc=lr=0; current_col<=NUM_COLS; current_col++ ) {
  150.               if ( carryover ) {
  151.                 filter_input(&line[0]);
  152.                 line[DISPLAYABLE] = '\0';
  153.                 if ( current_col != NUM_COLS )
  154.                     strncpy (&BUFFER[0][LEFT_EDGE], &line[0], strlen(line));
  155.                 else
  156.                     strcpy (&BUFFER[0][LEFT_EDGE], &line[0]);
  157.               };
  158.               for ( i=carryover; i < NUM_ROWS; i++ ) {
  159.                 carryover = 0;
  160.                 file_status = fgets (line, 159, INPUT);
  161.                 if (file_status == NULL) break;
  162.                 if ( FF && (line[0] == '\f') )
  163.                   if (i <= (NUM_ROWS+1)/2) i = carryover = (NUM_ROWS+1)/2;
  164.                   else  {carryover = 1; break; }
  165.                 filter_input(&line[0]);
  166.                 line[DISPLAYABLE] = '\0';
  167.                 if ( current_col != NUM_COLS )
  168.                     strncpy (&BUFFER[i][LEFT_EDGE], &line[0], strlen(line));
  169.                 else
  170.                     strcpy (&BUFFER[i][LEFT_EDGE], &line[0]);
  171.               };
  172.               if ( i > lr ) lr = i;
  173.               if (file_status == NULL) break;
  174.               LEFT_EDGE  = LEFT_EDGE + DISPLAYABLE + 1;
  175.               if ( carryover > 1 ) carryover = 0;
  176.             };
  177.  
  178.             /* Write out a page buffer and get ready for next page. */
  179.             for (i=0; i < lr; i++) {
  180.               j = strlen(&BUFFER[i][0]);
  181.               if (j)
  182.                 if (BUFFER[i][j-1] == '\n') j--;
  183.               if ( j > (NUM_CHAR - 1) ) j = NUM_CHAR - 1;
  184.               BUFFER[i][j]   = '\n';
  185.               BUFFER[i][j+1] = '\0';
  186.               fputs (&BUFFER[i][0], OUTPUT);
  187.             };
  188.             if (file_status != NULL) fputs ("\xc\0", OUTPUT);
  189.         } while (file_status);
  190.  
  191.         /* Send the printer termination string and close all files. */
  192.         fputs (PRINTER_TERM, OUTPUT);
  193.     fclose(INPUT);
  194.     fclose(OUTPUT);
  195. }
  196.  
  197. int     _nullcheck () {};
  198. int     _setenvp () {};
  199.  
  200.  
  201. int    print_copyright ()
  202.  
  203. {
  204.         fp